                                                                     
                                                                     
                                                                     
                                             
#include "header.h" 

int keyHex;

/**********************************************************/
/*      OUTPUT
/**********************************************************/

/**********************************************************/
// Initialize the UART interface, ACLK and stop watch dog timer
/**********************************************************/
void initUart(void)
{
  unsigned int i;
  WDTCTL = WDTPW + WDTHOLD;             // Stop WDT
  BCSCTL1 = XT2OFF;                     // ACLK = LFXT1 = HF XTAL

  do
  {
    IFG1 &= ~OFIFG;                     // Clear OSCFault flag
    for (i = 0xFF; i > 0; i--);         // Time for flag to set
  }
  while ((IFG1 & OFIFG) != 0);          // OSCFault flag still set?               

  BCSCTL2 = SELS;                       // SMCLK = XT2
  UCTL0 = CHAR;                         // 8-bit character
  UTCTL0 = SSEL1;                       // UCLK = ACLK
  UBR00 = 0x8B;                        
  UBR10 = 0x00;                         //
  UMCTL0 = 0x00;                        // no modulation
  ME1 |= UTXE0 + URXE0;                 // Enable USART0 TXD/RXD
  IE1 |= URXIE0;                        // Enable USART0 RX interrupt
  P3SEL |= 0x30;                        // P3.4,5 = USART0 TXD/RXD
  P3DIR |= 0x10;                        // P3.4 output direction
  _EINT();                              // Enable interrupts
}



/**********************************************************/
// UART Send Character Interrupt Routine
/**********************************************************/
void usart0_rx (void) __interrupt[UART0RX_VECTOR]
{
  while ((IFG1 & UTXIFG0) == 0);        // USART0 TX buffer ready?
  TXBUF0 = RXBUF0;                      // RXBUF0 to TXBUF0
}



/**********************************************************/
//  Prints a string of arbitrary length by calling printChar
/**********************************************************/
void printString(char* str){
  int i;


  for(i = 0;; i++){

    if(str[i] == '\0') 
      return;
    printChar(str[i]);
    }

}

/**********************************************************/
// Converts an int into ASCII and calls printChar repeteadly
/**********************************************************/
void printInt(int number){
  
  int i = 0;
  int digits[5];

  if(number == 0){
    printChar(48);
    return;
  }

  while(number > 0){
    digits[i++] = number%10;
    number /= 10;
  }
  i--;
  for(; i >= 0; i--)
    printChar(digits[i] + 48);
  
}

/**********************************************************/
// Sends an ACSCII character on the RS 232 interface
/**********************************************************/
void printChar(char letter){
  while ((IFG1 & UTXIFG0) == 0);        // USART0 TX buffer ready?
  TXBUF0 = letter;                      // RXBUF0 to TXBUF0
}


/**********************************************************/
// Prints the board
/**********************************************************/
void printBoard(char board[][SIZE+1], int showC[][SIZE+1]){
    
    int i, k;
    for(i =0; i < SIZE; i++){
      for(k = 0; k < SIZE; k++){
        if(showC[i][k] == 0)
          printString("* ");
        else{
          printChar(board[i][k]);
          printString(" ");
        }
      }
      printString("\r\n");
      
    }
    printString("\r\n");

}






/**********************************************************/
/*      INPUT
/**********************************************************/


/**********************************************************/
// Initialise the keyboard
// Set up the registers for keys and wait for a press
/**********************************************************/
  void initKeyboard(void){
    KEY = 0;
    P6DIR = 0xFF;
    BCSCTL1 = 0;
    P6OUT = (P6OUT & 0xf0)+0x0f; 
    P1IES = P1IES & 0xf1;  
    P1IFG = 0x0;
    P1IE = 0x0e;
    return;
  }

/**********************************************************/
// Called by ISR for key pressed. 
/*	Polls keys to find which got pressed and converts to int
/**********************************************************/
void keyScan(void){
   int keyMask = 1, counter = 4, dummy = 0;
  
    keyHex = 0;
    // Set all used P1 to 0 (f1 = 1111 0001)
    P1OUT = P1OUT & 0xf1;
   
    // Repeat 4 times
    while ( counter != 0 ){   
      P6OUT = P6OUT & 0xf0;           // Set voltage to all sending pins (rows) to 0
      P1DIR |= 0x0e;                  // Set direction of all the receiving pins (columns) to 1 (output)
      P1OUT = P1OUT & 0xf1;           // Clear extrea charge on all the colums (receiving) pins
      P1DIR = P1DIR & 0xf1;           // Send columns (receiving) pins back to inputs (0xf1 = 1111 0001) 

      // Poll the rows
      P6OUT = keyMask;                // Set pin 6.keymask to 1
      if ( (P1IN & 0x0e) != 0 )       // If one of the receiving pins (0000 1110) is not zero, key is still pressed
       {
       keyHex += keyMask;             // Record the row that sent the signal 
        dummy = P1IN & 0x0e;          // Dummy records the colums
        dummy = dummy<<4;                     // Shift everything to the upper 0x
        keyHex = keyHex + dummy;      // Record in keyhex
       }
      P6OUT = 0x0f;     
      keyMask = keyMask<<1;
      counter--;
    }//end while

    // Finally convert hardware into required key value
    switch(keyHex){
      case 0x21:      //0010 0001
        KEY = 7;
        break;
      case 0x22:      //0010 0010
        KEY = 10;
        break;
      case 0x24:   //0010 0100
        KEY = 1;
        break;
      case 0x28:   //0010 1000
        KEY = 4;
        break;
      case 0x41:   //0100 0001
        KEY = 8;
        break;
      case 0x42:   //0100 0010 
        KEY = 0;
        break;
      case 0x44:   //0100 0100 
        KEY = 2;
        break;
      case 0x48:   //0100 1000 
        KEY = 5;
        break;
      case 0x81:   //1000 0001 
        KEY = 9;
        break;
      case 0x82:   //1000 0010 
        KEY = 11;
        break;
      case 0x84:   //1000 0100 
        KEY = 3;
        break;
      case 0x88:   //1000 1000 
        KEY = 6;
        break;
      default:
        KEY = -1;
        break;
      }    
}





void initTimerB(void){
  TBCTL = TBSSEL1+TBCLR;
  TBCCTL0 = CCIE;
  TBCCR0 = 32767;
  TBCTL |= 0x10;
}

/**********************************************************/
/*	ISRs
/**********************************************************/
void RTC_TIMERB (void) __interrupt[TIMERB0_VECTOR]{

  TIME = TIME + 1;
  TBCTL = TBSSEL0+TBCLR;
  TBCCR0 = 32767;
  TBCTL |= 0x10;
}


/**********************************************************/
/*	When a key is pressed:
/*		Set timer A (for debouncing)
/*		Reset key pressed IFG to avoid coming back here during debounce
/*		GO back to main game and wait
/**********************************************************/
void PORT1_ISR (void) __interrupt[PORT1_VECTOR]{
  // Debounse: Set up Timer A to count 5000
  // Then wait for Timer A interrupt
  TACTL = TASSEL1+TACLR;
  TACCTL0 = CCIE;
  TACCR0 = 5000;
  TACTL |= 0x10;
  P1IFG = 0x0;
}


/**********************************************************/
/*	Once timerA is up => Debounce is over.
/*	Clear IFGs and launch polling to capture key pressed
/**********************************************************/
void Timer_A (void) __interrupt[TIMERA0_VECTOR]{
   TACTL = TACLR;
   TACCTL0 = 0;
   keyScan();
   P1IFG = 0x0;
   KEYPRESSED = 1;
   return;
}


